{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "filedir = 'Chapter16_ImageProcessingFiles'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image, ImageFilter\n",
    "\n",
    "kitten = Image.open(f'{filedir}/kitten.jpg')\n",
    "blurryKitten = kitten.filter(ImageFilter.GaussianBlur)\n",
    "blurryKitten.save(f'{filedir}/kitten_blurred.jpg')\n",
    "blurryKitten.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Beautiful is better than ugly.\n",
      "Explicit is better than implicit.\n",
      "Simple is better than complex.\n",
      "Complex is better than\n",
      "complicated.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from PIL import Image\n",
    "import pytesseract\n",
    "\n",
    "print(pytesseract.image_to_string(Image.open(f'{filedir}/test.png')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "B 102 502 152 567 0\n",
      "e 159 500 202 550 0\n",
      "a 210 500 254 550 0\n",
      "u 234 500 274 568 0\n",
      "t 262 501 300 549 0\n",
      "i 308 501 346 567 0\n",
      "f 353 502 376 568 0\n",
      "u 383 501 421 549 0\n",
      "l 433 502 441 567 0\n",
      "i 478 502 486 567 0\n",
      "s 495 500 534 550 0\n",
      "b 568 500 610 567 0\n",
      "e 616 500 659 550 0\n",
      "t 664 501 686 562 0\n",
      "t 690 501 712 562 0\n",
      "e 717 500 760 550 0\n",
      "r 770 502 793 550 0\n",
      "t 820 501 888 567 0\n",
      "h 874 500 906 567 0\n",
      "a 899 500 943 550 0\n",
      "n 951 502 989 550 0\n",
      "u 1026 501 1064 549 0\n",
      "g 1058 482 1090 567 0\n",
      "l 1074 482 1115 550 0\n",
      "y 1127 502 1135 567 0\n",
      ". 1142 483 1197 549 0\n",
      "E 77 393 125 458 0\n",
      "x 131 393 173 440 0\n",
      "p 158 374 197 458 0\n",
      "l 180 374 222 441 0\n",
      "i 231 393 259 458 0\n",
      "c 269 392 309 441 0\n",
      "i 317 393 325 458 0\n",
      "t 332 392 354 453 0\n",
      "i 387 393 395 458 0\n",
      "s 404 391 443 441 0\n",
      "b 477 391 519 458 0\n",
      "e 525 391 568 441 0\n",
      "t 573 392 595 453 0\n",
      "t 598 392 620 453 0\n",
      "e 625 391 668 441 0\n",
      "r 679 393 702 441 0\n",
      "t 729 392 751 453 0\n",
      "h 759 393 797 458 0\n",
      "a 807 391 851 441 0\n",
      "n 860 393 898 441 0\n",
      "i 935 393 943 458 0\n",
      "m 955 393 1018 441 0\n",
      "p 995 374 1042 458 0\n",
      "l 1029 374 1071 441 0\n",
      "i 1081 393 1089 458 0\n",
      "c 1101 393 1109 458 0\n",
      "i 1118 392 1158 441 0\n",
      "t 1166 393 1174 458 0\n",
      ". 1181 392 1222 453 0\n",
      "S 49 282 100 350 0\n",
      "i 111 284 119 349 0\n",
      "m 131 284 194 332 0\n",
      "p 179 265 220 350 0\n",
      "l 205 265 247 332 0\n",
      "e 256 282 316 349 0\n",
      "i 352 284 360 349 0\n",
      "s 369 282 408 332 0\n",
      "b 441 282 483 349 0\n",
      "e 490 282 533 332 0\n",
      "t 538 283 560 344 0\n",
      "t 563 283 585 344 0\n",
      "e 590 282 633 332 0\n",
      "r 643 284 666 332 0\n",
      "t 694 283 762 349 0\n",
      "h 749 282 790 349 0\n",
      "a 772 282 816 332 0\n",
      "n 824 284 862 332 0\n",
      "c 897 283 937 332 0\n",
      "o 942 282 986 332 0\n",
      "m 995 284 1058 332 0\n",
      "p 1042 265 1083 349 0\n",
      "l 1070 265 1112 332 0\n",
      "e 1121 282 1181 349 0\n",
      "x 1161 265 1201 349 0\n",
      ". 1186 284 1248 331 0\n",
      "C 202 173 259 241 0\n",
      "o 266 173 310 223 0\n",
      "m 319 175 382 223 0\n",
      "p 354 156 402 241 0\n",
      "l 394 156 436 223 0\n",
      "e 445 173 505 240 0\n",
      "x 510 175 552 222 0\n",
      "i 586 175 594 240 0\n",
      "s 603 173 642 223 0\n",
      "b 675 173 717 240 0\n",
      "e 723 173 766 223 0\n",
      "t 772 174 794 235 0\n",
      "t 797 174 819 235 0\n",
      "e 824 173 867 223 0\n",
      "r 877 175 900 223 0\n",
      "t 927 174 949 235 0\n",
      "h 958 175 996 240 0\n",
      "a 1006 173 1050 223 0\n",
      "n 1058 175 1096 223 0\n",
      "c 399 65 439 114 0\n",
      "o 444 64 488 114 0\n",
      "m 498 66 561 114 0\n",
      "p 536 47 583 131 0\n",
      "l 572 47 614 114 0\n",
      "i 623 66 651 131 0\n",
      "c 660 65 700 114 0\n",
      "a 707 64 751 114 0\n",
      "t 754 65 776 126 0\n",
      "e 781 64 824 114 0\n",
      "d 810 47 850 131 0\n",
      ". 831 64 896 131 0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(pytesseract.image_to_boxes(Image.open(f'{filedir}/test.png')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "level\tpage_num\tblock_num\tpar_num\tline_num\tword_num\tleft\ttop\twidth\theight\tconf\ttext\n",
      "1\t1\t0\t0\t0\t0\t0\t0\t1264\t670\t-1\t\n",
      "2\t1\t1\t0\t0\t0\t49\t102\t1199\t521\t-1\t\n",
      "3\t1\t1\t1\t0\t0\t49\t102\t1199\t521\t-1\t\n",
      "4\t1\t1\t1\t1\t0\t102\t102\t1095\t86\t-1\t\n",
      "5\t1\t1\t1\t1\t1\t102\t102\t339\t68\t96.726082\tBeautiful\n",
      "5\t1\t1\t1\t1\t2\t478\t103\t56\t67\t96.622643\tis\n",
      "5\t1\t1\t1\t1\t3\t568\t103\t225\t67\t96.359940\tbetter\n",
      "5\t1\t1\t1\t1\t4\t820\t103\t169\t67\t96.166580\tthan\n",
      "5\t1\t1\t1\t1\t5\t1026\t103\t171\t85\t96.646881\tugly.\n",
      "4\t1\t1\t1\t2\t0\t77\t212\t1145\t84\t-1\t\n",
      "5\t1\t1\t1\t2\t1\t77\t212\t277\t84\t96.551743\tExplicit\n",
      "5\t1\t1\t1\t2\t2\t387\t212\t56\t67\t96.863762\tis\n",
      "5\t1\t1\t1\t2\t3\t477\t212\t225\t67\t96.749100\tbetter\n",
      "5\t1\t1\t1\t2\t4\t729\t212\t169\t67\t96.655663\tthan\n",
      "5\t1\t1\t1\t2\t5\t935\t212\t287\t84\t65.345970\timplicit.\n",
      "4\t1\t1\t1\t3\t0\t49\t320\t1199\t85\t-1\t\n",
      "5\t1\t1\t1\t3\t1\t49\t320\t267\t85\t96.369377\tSimple\n",
      "5\t1\t1\t1\t3\t2\t352\t321\t56\t67\t96.018692\tis\n",
      "5\t1\t1\t1\t3\t3\t441\t321\t225\t67\t96.378403\tbetter\n",
      "5\t1\t1\t1\t3\t4\t694\t321\t168\t67\t96.207893\tthan\n",
      "5\t1\t1\t1\t3\t5\t897\t321\t351\t84\t96.207893\tcomplex.\n",
      "4\t1\t1\t1\t4\t0\t202\t429\t894\t85\t-1\t\n",
      "5\t1\t1\t1\t4\t1\t202\t429\t350\t85\t96.717308\tComplex\n",
      "5\t1\t1\t1\t4\t2\t586\t430\t56\t67\t95.620392\tis\n",
      "5\t1\t1\t1\t4\t3\t675\t430\t225\t67\t95.222137\tbetter\n",
      "5\t1\t1\t1\t4\t4\t927\t430\t169\t67\t95.222137\tthan\n",
      "4\t1\t1\t1\t5\t0\t399\t539\t497\t84\t-1\t\n",
      "5\t1\t1\t1\t5\t1\t399\t539\t497\t84\t92.677841\tcomplicated.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(pytesseract.image_to_data(Image.open(f'{filedir}/test.png')))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'level': [1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5], 'page_num': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'block_num': [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'par_num': [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'line_num': [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2], 'word_num': [0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, 6], 'left': [0, 23, 23, 23, 23, 76, 99, 164, 215, 295, 317, 378, 425, 467, 500, 555, 23, 23, 140, 198, 239, 304, 407], 'top': [0, 26, 26, 26, 26, 26, 30, 26, 26, 26, 26, 26, 26, 26, 26, 26, 54, 55, 55, 59, 59, 55, 54], 'width': [600, 555, 555, 555, 44, 15, 57, 42, 70, 15, 52, 40, 32, 24, 45, 23, 513, 107, 49, 32, 57, 92, 129], 'height': [103, 51, 51, 22, 17, 17, 13, 21, 17, 17, 21, 17, 17, 17, 17, 22, 23, 17, 17, 13, 13, 22, 23], 'conf': [-1, -1, -1, -1, 96, 96, 96, 95, 96, 96, 96, 96, 96, 96, 96, 96, -1, 96, 96, 96, 96, 92, 65], 'text': ['', '', '', '', 'This', 'is', 'some', 'text,', 'written', 'in', 'Arial,', 'that', 'will', 'be', 'read', 'by', '', 'Tesseract.', 'Here', 'are', 'some', 'symbols:', '!|@#$%&*()']}\n",
      "b'This is some text, written in Arial, that will be read by\\nTesseract. Here are some symbols: !|@#$%&*()\\n'\n"
     ]
    }
   ],
   "source": [
    "from PIL import Image\n",
    "import pytesseract\n",
    "from pytesseract import Output\n",
    "\n",
    "print(pytesseract.image_to_data(Image.open(f'{filedir}/'\n",
    "    'textOriginal.png'),\n",
    "    output_type=Output.DICT))\n",
    "print(pytesseract.image_to_string(Image.open(f'{filedir}/textOriginal.png'), output_type=Output.BYTES))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.280350850198276\n",
      "100.0\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "numbers = [100, 102, 98, 97, 103]\n",
    "print(np.std(numbers))\n",
    "print(np.mean(numbers))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is some text, written in Arial, that will be read by\n",
      "Tesseract Here are some symbols: |@#$%*&\"(}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from PIL import Image\n",
    "import pytesseract\n",
    "\n",
    "def cleanFile(filePath, newFilePath):\n",
    "    image = Image.open(filePath)\n",
    "\n",
    "    #Set a threshold value for the image, and save\n",
    "    image = image.point(lambda x: 0 if x<143 else 255)\n",
    "    image.save(newFilePath)\n",
    "    return image\n",
    "\n",
    "image = cleanFile(f'{filedir}/textBad.png', f'{filedir}/textCleaned.png')\n",
    "\n",
    "#call tesseract to do OCR on the newly created image\n",
    "print(pytesseract.image_to_string(image))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is some text, written in Arial, that will be read by\n",
      "Tesseract. Here are some symbols: !|@#$%*&*()\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Estimating resolution as 218\n"
     ]
    }
   ],
   "source": [
    "from PIL import Image\n",
    "import subprocess\n",
    "\n",
    "def cleanFile(filePath, newFilePath):\n",
    "    image = Image.open(filePath)\n",
    "\n",
    "    #Set a threshold value for the image, and save\n",
    "    image = image.point(lambda x: 0 if x<135 else 255)\n",
    "    image.save(newFilePath)\n",
    "\n",
    "    #call tesseract to do OCR on the newly created image\n",
    "    subprocess.call(['tesseract', newFilePath, 'output'])\n",
    "    \n",
    "    #Open and read the resulting data file\n",
    "    outputFile = open('output.txt', 'r')\n",
    "    print(outputFile.read())\n",
    "    outputFile.close()\n",
    "\n",
    "cleanFile(f'{filedir}/textOriginal.png', f'{filedir}/text_2.png')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "threshold: 80, confidence: 48.666666666666664, numChars: 18\n",
      "threshold: 85, confidence: 64.65217391304348, numChars: 23\n",
      "threshold: 90, confidence: 45.5945945945946, numChars: 37\n",
      "threshold: 95, confidence: 39.48717948717949, numChars: 39\n",
      "threshold: 100, confidence: 56.310344827586206, numChars: 58\n",
      "threshold: 105, confidence: 52.943661971830984, numChars: 71\n",
      "threshold: 110, confidence: 68.16867469879519, numChars: 83\n",
      "threshold: 115, confidence: 73.82926829268293, numChars: 82\n",
      "threshold: 120, confidence: 75.52380952380952, numChars: 84\n",
      "threshold: 125, confidence: 82.45882352941176, numChars: 85\n",
      "threshold: 130, confidence: 75.22619047619048, numChars: 84\n",
      "threshold: 135, confidence: 87.78313253012048, numChars: 83\n",
      "threshold: 140, confidence: 83.44705882352942, numChars: 85\n",
      "threshold: 145, confidence: 88.72619047619048, numChars: 84\n",
      "threshold: 150, confidence: 81.7710843373494, numChars: 83\n",
      "threshold: 155, confidence: 87.72151898734177, numChars: 79\n",
      "threshold: 160, confidence: 84.275, numChars: 80\n",
      "threshold: 165, confidence: 87.65714285714286, numChars: 70\n",
      "threshold: 170, confidence: 93.49295774647888, numChars: 71\n",
      "threshold: 175, confidence: 94.74626865671642, numChars: 67\n",
      "threshold: 180, confidence: 92.30882352941177, numChars: 68\n",
      "threshold: 185, confidence: 90.41269841269842, numChars: 63\n",
      "threshold: 190, confidence: 93.484375, numChars: 64\n",
      "threshold: 195, confidence: 93.66176470588235, numChars: 68\n"
     ]
    }
   ],
   "source": [
    "import pytesseract\n",
    "from pytesseract import Output\n",
    "from PIL import Image\n",
    "import numpy as np\n",
    "\n",
    "def cleanFile(filePath, threshold):\n",
    "    image = Image.open(filePath)\n",
    "    #Set a threshold value for the image, and save\n",
    "    image = image.point(lambda x: 0 if x<threshold else 255)\n",
    "    return image\n",
    "\n",
    "def getConfidence(image):\n",
    "    data = pytesseract.image_to_data(image, output_type=Output.DICT)\n",
    "    text = data['text']\n",
    "    confidences = []\n",
    "    numChars = []\n",
    "    \n",
    "    for i in range(len(text)):\n",
    "        if data['conf'][i] > -1:\n",
    "            confidences.append(data['conf'][i])\n",
    "            numChars.append(len(text[i]))\n",
    "            \n",
    "    return np.average(confidences, weights=numChars), sum(numChars)\n",
    "    \n",
    "filePath = f'{filedir}/textBad.png'\n",
    "\n",
    "start = 80\n",
    "step = 5\n",
    "end = 200\n",
    "\n",
    "for threshold in range(start, end, step):\n",
    "    image = cleanFile(filePath, threshold)\n",
    "    scores = getConfidence(image)\n",
    "    print(f'threshold: {threshold}, confidence: {scores[0]}, numChars: {scores[1]}')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[WDM] - Downloading: 100%|███████████████████████████████████████████████████████████████████████████████████████████| 8.81M/8.81M [00:00<00:00, 28.7MB/s]\n"
     ]
    }
   ],
   "source": [
    "from webdriver_manager.chrome import ChromeDriverManager\n",
    "CHROMEDRIVER_PATH = ChromeDriverManager().install()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Found the iframe\n",
      "Found the images!\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S001.LXXXXXXX.jpg?Expires=1685677502&Signature=WtvgKtT-FABibf3pMsskBL6FJ5cCFom46Eis~hL68HFs3q2kDSqKmt4jfblK0-DlzHGigb6w4Gum0uUEKj4WLAYu4HdYlvj6A~DCLF5hICrg3ms1rVz073Q7cMF6HelAu~VMDAlUlbg3Fgtdg60P4wKrFm0~GogOjmO3sw7LjfA_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "; ighted Material\n",
      "Rees EasyRead Large Edition @\n",
      "\n",
      "The Death of Ivan Ilyich\n",
      "\n",
      "Leo Nikolayevich Tolstoy\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S002.JUMBOXXX.jpg?Expires=1685677508&Signature=Yhred2InU~vXDwzq69WTaN3IKaBtGZac0N-JxzL8Ul5zMS-X7-J9VowQMT3afm1ZTCVQXWth3bBuZxJI6YyBMeuVzH2iPXj6p78lQuY7cEYY0ocyuwpq1IL0uwcx9TjKvTOU47jKdLgWX7NVKKz-FwtOEEsW86-VDxtJON4JLfY_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "The Death of Ivan Ilyich\n",
      "\n",
      "By\n",
      "Leo Nikolayevich Tolstoy\n",
      "\n",
      "@\n",
      "\n",
      "EasyRead Large\n",
      "\n",
      "ReadHowYouWant Classics Library\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S003.LXXXXXXX.jpg?Expires=1685677502&Signature=fDjl88dlro6TqrMSLQ-r1tX9AQw2DXVPudunKEcOeNdiNNpYwZOP6vKB~8wqMQuRRpjwXSJSYbiWEDluzac3mz3DmaHcrOx~3~KkzlWAYBjjdnRJEt9J2o~n0O5yaLMpI3pf8giwO6DjRrGEEp3HLh0cYtBQeziXo6cUt3Mjz54_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "Copyright © 2007\n",
      "\n",
      "The text in this book has been formatted\n",
      "and typeset to make reading easier and\n",
      "more enjoyable. Spelling and punctuation\n",
      "have been modernized and standardized,\n",
      "and hyphens have been avoided when\n",
      "possible. Obvious typographical errors\n",
      "have been corrected. In addition, the text\n",
      "has been formatted to the specifications\n",
      "indicated on the title page. The original\n",
      "text is out of copyright. The edited text in\n",
      "this edition and the formatting are the\n",
      "copyright of Objective Systems Pty Ltd\n",
      "ACN 085 119 953.\n",
      ". am\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S004.JUMBOXXX.jpg?Expires=1685677508&Signature=D9eoRDCUgmbdUkDEtMgi-pxV6cxp5MIz2s9KFVrVpR6yj5H1jTlRxrGpfMl36jOXsIlY2kTw7J1OM~fG6whvTm24IxuJM1Xzt48WbdNjP-XSpORfOno5OwEAPv1z3Fb~OEWQX6EHjs-~NIIBeZb5p0NcbLbzqjCG1En8cG4nyUc_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "ReadHowYouWant provides access to\n",
      "great literature for all readers. We are\n",
      "committed to bringing you the largest\n",
      "library of classic literature and to\n",
      "making reading as effortless as\n",
      "possible.\n",
      "\n",
      "We offer high-quality editions of the\n",
      "complete works of all the major literary\n",
      "authors, plus critical books about each\n",
      "author's life and works. Various\n",
      "editions of many titles are available,\n",
      "and for texts not written in English, we\n",
      "are often able to offer a choice of\n",
      "translations.\n",
      "\n",
      "Our goal is to make reading easier,\n",
      "more enjoyable, and accessible to all\n",
      "readers. And for readers who need\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S006.LXXXXXXX.jpg?Expires=1685677502&Signature=MOtwItwZhfQ4og1O2aqgRLw2qT9I0CcEqZmWkQJrIGdRRasdYJ-8Ykgnk1oNrXVT9lrbC9NB-KLlPorludMmaC327fsNKL2N2DkFBhgvz~JaGx0niT5KryBODoisXWqkJ3HJdd4xdMwbMxTKC5n2DnGlL4t6GBfhynJcuAUnL3c_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "TABLE OF CONTENTS\n",
      "\n",
      "Chapter I 1\n",
      "Chapter II 7\n",
      "Chapter IIT 31\n",
      "Chapter IV 43\n",
      "Chapter V 55\n",
      "Chapter VI 63\n",
      "Chapter VII 69\n",
      "Chapter VIII 7\n",
      "Chapter 1x 91\n",
      "Chapter X 97\n",
      "Chapter XI 101\n",
      "Chapter XII 107\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S007.JUMBOXXX.jpg?Expires=1685677508&Signature=g0Sxt2~bVpD2m51G47Bq8WUuOdrf8N56bx1MBl2Ktna3lXWv7aKJZALjurzkUlodE9-6FJ0eomFiD2VkXVsd0NXToNZziY7pH8~a8q1tCF4xaL3Kt0WKfkgvqJJaChhIzZxM17sCoQtoyCT2H1fJsUV~hoQLqwBy5bYjODDb0VY_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S008.LXXXXXXX.jpg?Expires=1685677502&Signature=J1XQ08proRL27gbvsYedJmqjJ10vDAizdRBv4fwbq7DNf1zuuvc4i0EQr5hpsoJMQ4QL2q0jBQciRU8-s-cVM4CMFx8ccAy8TCgNRZUaMOna1qFC-iRKdJckendibh3~nsIzeuvOgI8EIg0YCPMIjD6XGzUYjyae7mfACkcL~iE_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "Chapter I\n",
      "\n",
      "During an interval in the Melvinski trial in the large\n",
      "building of the Law Courts the members and public\n",
      "prosecutor met in Ivan Egorovich Shebek's private\n",
      "room, where the conversation turned on the celebrated\n",
      "Krasovski case. Fedor Vasilievich warmly maintained\n",
      "that it was not subject to their jurisdiction, Ivan\n",
      "Egorovich maintained the contrary, while Peter\n",
      "Ivanovich, not having entered into the discussion at\n",
      "the start, took no part in it but looked through the\n",
      "Gazette which had just been handed in.\n",
      "\n",
      "“Gentlemen,” he said, “Ivan Ilych has died!”\n",
      "“You don't say so!”\n",
      "\n",
      "“Here, read it yourself,” replied Peter Ivanovich,\n",
      "handing Fedor Vasilievich the paper still damp from\n",
      "the press. Surrounded by a black border were the\n",
      "words: “Praskovya Fedorovna Golovina, with profound\n",
      "sorrow, informs relatives and friends of the demise\n",
      "of her beloved husband Ivan Ilych Golovin, Member\n",
      "of the Court of Justice, which occurred on February\n",
      "the 4th of this year 1882. The funeral will take place\n",
      "on Friday at one o'clock in the afternoon.”\n",
      "\n",
      "Ivan Ilych had been a colleague of the gentlemen\n",
      "present and was liked by them all. He had been ill for\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S009.JUMBOXXX.jpg?Expires=1685677508&Signature=VrfJ-mgdmnFke~TaqC5rBUkvuUhRdn-8YYMNUNysWyxRAl~Moy6DqKHQuHVud-JsWVGhJOSPNEvgKlQVAQTKAQtX3flbc4b-bTlhc3kLM7CFiVpVUaFGWE7lkw2vWLCKjITwwCUBmlzmj9nz-n-FYGjZSvQKISMGzeDFeXEhAQo_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "some weeks with an illness said to be incurable.\n",
      "His post had been kept open for him, but there\n",
      "had been conjectures that in case of his death\n",
      "Alexeev might receive his appointment, and that\n",
      "either Vinnikov or Shtabel would succeed Alexeev.\n",
      "So on receiving the news of Ivan Ilych's death the\n",
      "first thought of each of the gentlemen in that pri-\n",
      "vate room was of the changes and promotions it\n",
      "might occasion among themselves or their acquain-\n",
      "tances.\n",
      "\n",
      "“I shall be sure to get Shtabel's place or Vin-\n",
      "nikov's,” thought Fedor Vasilievich. “I was promised\n",
      "that long ago, and the promotion means an extra\n",
      "eight hundred rubles a year for me besides the\n",
      "allowance.”\n",
      "\n",
      "“Now I must apply for my brother-in-law's transfer\n",
      "from Kaluga,” thought Peter Ivanovich. “My wife\n",
      "will be very glad, and then she won't be able to\n",
      "say that I never do anything for her relations.”\n",
      "\n",
      "“I thought he would never leave his bed again,”\n",
      "said Peter Ivanovich aloud. “It's very sad.”\n",
      "\n",
      "“But what really was the matter with him?”\n",
      "\n",
      "“The doctors couldn't say - at least they could,\n",
      "but each of them said something different. When\n",
      "last I saw him I though he was getting better.”\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S00A.JUMBOXXX.jpg?Expires=1685677508&Signature=S~pAmxAheXTCpmhdEx0wiixoWXUF7H97uhoKsXjZ~YI9CIg2frcBhOXTYM4rCTlo5U6m~Mi2wP35~~5YN28g32QYAEpAod2ida1TgD7W8uTlHSAy67Obu2fx9ulJiBlNZRoMdhmDlcx89U4Jb0VEG31rQJpcj9vVev3n0eTtEVM_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "“And I haven't been to see him since the holidays.\n",
      "I always meant to go.”\n",
      "\n",
      "“Had he any property?”\n",
      "\n",
      "“I think his wife had a little - but something quiet\n",
      "trifling.”\n",
      "\n",
      "“We shall have to go to see her, but they live so\n",
      "terribly far away.”\n",
      "\n",
      "“Far away from you, you mean. Everything's far\n",
      "away from your place.”\n",
      "\n",
      "“You see, he never can forgive my living on the\n",
      "other side of the river,” said Peter Ivanovich,\n",
      "smiling at Shebek. Then, still talking of the dis-\n",
      "tances between different parts of the city, they\n",
      "returned to the Court.\n",
      "\n",
      "Besides considerations as to the possible transfers\n",
      "and promotions likely to result from Ivan Ilych's\n",
      "death, the mere fact of the death of a near acquain-\n",
      "tance aroused, as usual, in all who heard of it the\n",
      "complacent feeling that, “it is he who is dead and\n",
      "not I.”\n",
      "\n",
      "Each one thought or felt, “Well, he's dead but I'm\n",
      "alive!” But the more intimate of Ivan Ilych's ac-\n",
      "quaintances, his so-called friends, could not help\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S00B.JUMBOXXX.jpg?Expires=1685677508&Signature=Nx1kL5ISZDQcZXKgVy9077kiiggfEHmQEVdMTLBR8dQNMRswWjeqDCDgzsXKEP8vnuKgqp0HmPIieWqSf2jGSONWgmkCmGfSzwm5l34S0YHWKVXpoUwI8x1AqhZWz59Q1vP97ZGXNZ~vMXFG3af7hhuOEwiGEZmO9~ttlKDk6tY_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Copyrighted Material\n",
      "\n",
      "thinking also that they would now have to fulfil\n",
      "the very tiresome demands of propriety by attend-\n",
      "ing the funeral service and paying a visit of condo-\n",
      "lence to the widow.\n",
      "\n",
      "Fedor Vasilievich and Peter Ivanovich had been\n",
      "his nearest acquaintances. Peter Ivanovich had\n",
      "studied law with Ivan Ilych and had considered\n",
      "himself to be under obligations to him.\n",
      "\n",
      "Having told his wife at dinner-time of Ivan Ilych's\n",
      "death, and of his conjecture that it might be pos-\n",
      "sible to get her brother transferred to their circuit,\n",
      "Peter Ivanovich sacrificed his usual nap, put on\n",
      "his evening clothes and drove to Ivan Ilych's\n",
      "house.\n",
      "\n",
      "At the entrance stood a carriage and two cabs.\n",
      "Leaning against the wall in the hall downstairs\n",
      "near the cloakstand was a coffin-lid covered with\n",
      "cloth of gold, ornamented with gold cord and tas-\n",
      "sels, that had been polished up with metal powder.\n",
      "Two ladies in black were taking off their fur cloaks.\n",
      "Peter Ivanovich recognized one of them as Ivan\n",
      "Ilych's sister, but the other was a stranger to him.\n",
      "His colleague Schwartz was just coming down-\n",
      "stairs, but on seeing Peter Ivanovich enter he\n",
      "stopped and winked at him, as if to say: “Ivan\n",
      "Ilych has made a mess of things - not like you\n",
      "and me.”\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S00C.JUMBOXXX.jpg?Expires=1685677508&Signature=DmfYc1jlrJRrCgosb7NDsrRxXkuXRnGJpKhnFzmooUt1sxY3ec8-2j0I7LfKEubnu4xhnLgAw8a~tNUv0MrZm5y92vCLXESi88mVde9Ah7IiWnTKmF33UISKDhcBJghyghci2uuvbtaUnDNGWlxoi4xfzb5MCD7zL-Wtv5X9oWs_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "Schwartz's face with his Piccadilly whiskers, and\n",
      "his slim figure in evening dress, had as usual an\n",
      "air of elegant solemnity which contrasted with the\n",
      "playfulness of his character and had a special pi-\n",
      "quancy here, or so it seemed to Peter Ivanovich.\n",
      "\n",
      "Peter Ivanovich allowed the ladies to precede him\n",
      "and slowly followed them upstairs. Schwartz did\n",
      "not come down but remained where he was, and\n",
      "Peter Ivanovich understood that he wanted to ar-\n",
      "range where they should play bridge that evening.\n",
      "The ladies went upstairs to the widow's room, and\n",
      "Schwartz with seriously compressed lips but a\n",
      "playful looking his eyes, indicated by a twist o\n",
      "his eyebrows the room to the right where the body\n",
      "ay.\n",
      "\n",
      "Peter Ivanovich, like everyone else on such occa-\n",
      "sions, entered feeling uncertain what he would\n",
      "have to do. All he knew was that at such times i\n",
      "is always safe to cross oneself. But he was not\n",
      "quite sure whether one should make obseisances\n",
      "while doing so. He therefore adopted a middle\n",
      "course. On entering the room he began crossing\n",
      "himself and made a slight movement resembling\n",
      "a bow. At the same time, as far as the motion of\n",
      "his head and arm allowed, he surveyed the room.\n",
      "Two young men - apparently nephews, one of\n",
      "whom was a high-school pupil - were leaving the\n",
      "room, crossing themselves as they did so. An old\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S00D.JUMBOXXX.jpg?Expires=1685677508&Signature=N4kdRBmVqt0PO5V65v~M5PcCpeRc75qJ2xwikFODSRRbqp4TnKXwbfZqB-iCS3Ev-hxtjSvrRUpiq0cnogqGKSo~CHwgjStF7HB7sJx8L9hzWP15VFfRVmw-tRCChLnkXYqH-j5B0zaPcXucuASOe64PnBuN7FNLC2SOYNQsoYc_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "woman was standing motionless, and a lady with\n",
      "strangely arched eyebrows was saying something to\n",
      "her in a whisper. A vigorous, resolute Church Reader,\n",
      "in a frock-coat, was reading something in a loud\n",
      "voice with an expression that precluded any contra-\n",
      "diction. The butler's assistant, Gerasim, stepping\n",
      "lightly in front of Peter Ivanovich, was strewing\n",
      "something on the floor. Noticing this, Peter Ivanovich\n",
      "was immediately aware of a faint odour of a decom-\n",
      "posing body.\n",
      "\n",
      "The last time he had called on Ivan Ilych, Peter\n",
      "Ivanovich had seen Gerasim in the study. Ivan Ilych\n",
      "had been particularly fond of him and he was per-\n",
      "forming the duty of a sick nurse.\n",
      "\n",
      "Peter Ivanovich continued to make the sign of the\n",
      "cross slightly inclining his head in an intermediate\n",
      "direction between the coffin, the Reader, and the\n",
      "icons on the table in a corner of the room. After-\n",
      "wards, when it seemed to him that this movement\n",
      "of his arm in crossing himself had gone on too long,\n",
      "he stopped and began to look at the corpse.\n",
      "\n",
      "The dead man lay, as dead men always lie, in a\n",
      "specially heavy way, his rigid limbs sunk in the soft\n",
      "cushions of the coffin, with the head forever bowed\n",
      "on the pillow. His yellow waxen brow with bald\n",
      "patches over his sunken temples was thrust up in\n",
      "the way peculiar to the dead, the protruding nose\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "Found image: https://d1b14unh5d6w7g.cloudfront.net/1427027277.01.S03E.LXXXXXXX.jpg?Expires=1685677502&Signature=C~N6IWoWQqz6W2puEbfTRKKA5fnKlq7Qued77Y5NEfu2gTdxc-2WvqokWAe-931lt410hlDO8gcRX2kVpxHcdIhKYx~ytz2aqMRzAPrPOEM5cK1Jcbtza9Ho0akY~Y3SruT69evRPEp7yn1kQjJ3CyMMirMWkAPjxqMgw2ZDb-s_&Key-Pair-Id=APKAIUO27P366FGALUMQ\n",
      "Copyrighted Material\n",
      "\n",
      "Leo Tolstoy was a Russian novelist MAMAS Rapanene\n",
      "\n",
      "4 and moral philosopher noted for stiovabic ee posiile. We elfer\n",
      "9 all books in our Classics Library\n",
      "his ideas of nonviolent resistance.\n",
      "in a wide range of standard\n",
      "\n",
      "and large-type formats, and\n",
      "\n",
      "His diary reveals an incessant pursuit\n",
      "« of a morally justified life. He was\n",
      "\n",
      "formats for people with\n",
      "J g Exot Sor TE Generoeiy to the reading difficulties—all\n",
      "\n",
      "if optimized for readability—so\n",
      "- PGR ECU Ee | “eade’s can choose the format\n",
      "Peace” (1869), which Tolstoy regarded as an epic that suits them best. See inside\n",
      "rather than a novel, and “Anna Karenina” (1877). [iaaiula\n",
      "His work was admired in his time by Dostoyevsky,\n",
      "Checkoy, Turgeney, and Flaubert, and later by This EasyRead Large\n",
      "\n",
      "Virginia Woolf and James Joyce. Edition is apumized for\n",
      "readers who need a\n",
      "\n",
      "A masterpiece in which Tolstoy's writing prowess dard 16pt | @\n",
      "\n",
      "reaches its zenith. It focusses on a subject close to aeaiMNaaaMialiba Aaah Aina\n",
      "\n",
      "human life - death. The issue is introduced through\n",
      "\n",
      "the character of a high court judge who recognizes,\n",
      "after death stares him in the face, that his life has\n",
      "been pointless and devoid of meaning. Moving and.\n",
      "\n",
      "insightful!\n",
      "\n",
      "9785142702. 727-6\n",
      "\n",
      "Copyrighted Material\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "from urllib.request import urlretrieve\n",
    "from PIL import Image\n",
    "import pytesseract\n",
    "from selenium import webdriver\n",
    "from selenium.webdriver.chrome.service import Service\n",
    "from selenium.webdriver.common.by import By\n",
    "from selenium.webdriver.support.ui import WebDriverWait\n",
    "from selenium.webdriver.support import expected_conditions as EC\n",
    "from selenium.common.exceptions import TimeoutException\n",
    "\n",
    "from PIL import Image\n",
    "\n",
    "\n",
    "def image_to_text(image):\n",
    "    urlretrieve(image, 'page.jpg')\n",
    "    imageList.append(image)\n",
    "    print(pytesseract.image_to_string(Image.open('page.jpg')))\n",
    "\n",
    "# Create new Selenium driver\n",
    "driver = webdriver.Chrome(service=Service(CHROMEDRIVER_PATH))\n",
    "\n",
    "driver.get(\n",
    "    'https://www.amazon.com/Death-Ivan-Ilyich-Nikolayevich-Tolstoy/dp/1427027277')\n",
    "\n",
    "# Click on the book preview button\n",
    "driver.find_element(By.ID, 'litb-canvas-click-wrapper').click()\n",
    "try:\n",
    "    WebDriverWait(driver, 600).until(EC.presence_of_element_located((By.ID, 'litb-read-frame')))\n",
    "except TimeoutException:\n",
    "    print('Did not find the iframe')\n",
    "frame = driver.find_element(By.ID, 'litb-read-frame')\n",
    "driver.switch_to.frame(frame)\n",
    "\n",
    "try:\n",
    "    WebDriverWait(driver, 600).until(EC.presence_of_element_located((By.ID, 'kr-renderer')))\n",
    "except TimeoutException:\n",
    "    print('Did not find the images')\n",
    "images = driver.find_elements(By.XPATH, '//div[@data-page]/img')\n",
    "#images = driver.find_element(By.ID, 'renderer-container').find_elements(By.TAG_NAME, 'img')\n",
    "for image in images:\n",
    "    image_url = image.get_attribute('src')\n",
    "    image_to_text(image_url)\n",
    "\n",
    "driver.quit()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CAPTCHA Processing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bs4 import BeautifulSoup\n",
    "from urllib.request import urlopen\n",
    "from urllib.request import urlretrieve\n",
    "import os \n",
    "\n",
    "if not os.path.exists('captchas'):\n",
    "    os.mkdir('captchas')\n",
    "\n",
    "for i in range(0, 200):\n",
    "    bs = BeautifulSoup(urlopen('https://pythonscraping.com/humans-only/'))\n",
    "    imgUrl = bs.find('img', {'class': 'wpcf7-captchac'})['src']\n",
    "    urlretrieve(imgUrl, f'captchas/{imgUrl.split(\"/\")[-1]}')   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from PIL import Image, ImageOps\n",
    "\n",
    "def cleanImage(imagePath):\n",
    "    image = Image.open(imagePath)\n",
    "    image = image.point(lambda x: 255 if x<143 else 0)\n",
    "    borderImage = ImageOps.expand(image,border=20,fill='white')\n",
    "    borderImage.save(imagePath)\n",
    "    \n",
    "for filename in os.listdir('captchas'):\n",
    "    if '.png' in filename:\n",
    "        cleanImage(f'captchas/{filename}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1535080030\n",
      "Captcha solution attempt: X9SU\n",
      "{\"contact_form_id\":93,\"status\":\"mail_sent\",\"message\":\"Thank you for your message. It has been sent.\",\"posted_data_hash\":\"2bc8d1e0345bbfc281eac0410fc7b80d\",\"into\":\"#wpcf7-f93-o1\",\"invalid_fields\":[],\"captcha\":{\"captcha-170\":\"https:\\/\\/pythonscraping.com\\/wp-content\\/uploads\\/wpcf7_captcha\\/3551342528.png\"}}\n"
     ]
    }
   ],
   "source": [
    "from urllib.request import urlretrieve\n",
    "from urllib.request import urlopen\n",
    "from bs4 import BeautifulSoup\n",
    "import subprocess\n",
    "import requests\n",
    "from PIL import Image, ImageOps\n",
    "import json\n",
    "\n",
    "def cleanImage(imagePath):\n",
    "    image = Image.open(imagePath)\n",
    "    image = image.point(lambda x: 255 if x<143 else 0)\n",
    "    borderImage = ImageOps.expand(image,border=20,fill='white')\n",
    "    borderImage.save(imagePath)\n",
    "\n",
    "    \n",
    "def getCaptchaSolution(hiddenToken):\n",
    "    imageLocation = f'https://pythonscraping.com/wp-content/uploads/wpcf7_captcha/{hiddenToken}.png'\n",
    "    urlretrieve(imageLocation, 'captcha.png')\n",
    "    cleanImage('captcha.png')\n",
    "    p = subprocess.Popen(['tesseract','-l', 'captcha', 'captcha.png', 'output'], stdout=subprocess.PIPE,stderr=subprocess.PIPE)\n",
    "    p.wait()\n",
    "    f = open('output.txt', 'r')\n",
    "\n",
    "    #Clean any whitespace characters\n",
    "    captchaResponse = f.read().replace(' ', '').replace('\\n', '')\n",
    "    print('Captcha solution attempt: '+captchaResponse)\n",
    "    return captchaResponse\n",
    "\n",
    "html = urlopen('https://www.pythonscraping.com/humans-only')\n",
    "bs = BeautifulSoup(html, 'html.parser')\n",
    "#Gather prepopulated form values\n",
    "hiddenToken = bs.find('input', {'name':'_wpcf7_captcha_challenge_captcha-170'})['value']\n",
    "\n",
    "print(hiddenToken)\n",
    "\n",
    "name = 'Ryan'\n",
    "email = 'ryan.e.mitchell@gmail.com'\n",
    "subject = 'A very human subject'\n",
    "message = 'A message about Python and other human stuff'\n",
    "captcha_solution= getCaptchaSolution(hiddenToken)\n",
    "\n",
    "form_data = f'''\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"_wpcf7\"\n",
    "\n",
    "93\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"_wpcf7_version\"\n",
    "\n",
    "5.7.7\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"_wpcf7_locale\"\n",
    "\n",
    "en_US\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"_wpcf7_unit_tag\"\n",
    "\n",
    "wpcf7-f93-o1\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"_wpcf7_container_post\"\n",
    "\n",
    "0\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"_wpcf7_posted_data_hash\"\n",
    "\n",
    "\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"your-name\"\n",
    "\n",
    "{name}\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"your-email\"\n",
    "\n",
    "{email}\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"your-subject\"\n",
    "\n",
    "{subject}\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"your-message\"\n",
    "\n",
    "{message}\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"_wpcf7_captcha_challenge_captcha-170\"\n",
    "\n",
    "{hiddenToken}\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco\n",
    "Content-Disposition: form-data; name=\"captcha-170\"\n",
    "\n",
    "{captcha_solution}\n",
    "------WebKitFormBoundaryBFvsPGsghJe0Esco--\n",
    "'''\n",
    "\n",
    "if len(captcha_solution) == 4:\n",
    "    formSubmissionUrl = 'https://pythonscraping.com/wp-json/contact-form-7/v1/contact-forms/93/feedback'\n",
    "    headers = {'Content-Type': 'multipart/form-data;boundary=----WebKitFormBoundaryBFvsPGsghJe0Esco'}\n",
    "    r = requests.post(formSubmissionUrl, data=form_data, headers=headers)\n",
    "    print(r.text)\n",
    "else:\n",
    "    print('There was a problem reading the CAPTCHA correctly!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
